
package domain;

import java.util.Iterator;
import java.util.Vector;

/**
 *
 * @author shaigi
 */
public class Game {

    public static enum  action { RIGHT, LEFT, UP, DOWN, SHOOT };

    // configurations:
    public static final int 		STEP_COST   	= 1;
    public static final int 		FLAG_VALUE  	= 70;
    public static final int 		NO_FLAG     	= 0;
    public static final int 		DELAY       	= 400;
    public static final int 		INITIALE_SCORE 	= 0;
	public static final double 		PROBABILITY 	= 0.001;


	public static Board     		_board;
    private static Vector<Agent>	_agents;
    private int             		_maxSteps;
    public static boolean			_gameDeterministic;
    private static boolean			_gameZeroSum;
    private double					_slippingOnIceProbability;
    //private int						_arsenal;
    private String					_assignment;



public Game(Board board, boolean gameDeterministic, boolean gameZeroSum, int arsenal, String assignment) {

        Game._board     				= board;
        Game._agents    				= new Vector<Agent>();
        Game._gameDeterministic			= gameDeterministic;
        Game._gameZeroSum				= gameZeroSum;
        setSlippingOnIceProbability(PROBABILITY);
        //this._arsenal					= arsenal;
        this._assignment				= assignment;

        System.out.println("Game created, p = " + this._slippingOnIceProbability);
    }

	public static double getProbability(){
		if (Game._gameDeterministic){
			return 0.0;
		}
		return Game.PROBABILITY;
	}

    private void setSlippingOnIceProbability(double ignoreIfDeterministic_probability) {
		if ( Game._gameDeterministic ){
			this._slippingOnIceProbability = 0.0;	// this is the probability' of succeeding escaping the ice!
		}
		else{
			this._slippingOnIceProbability = ignoreIfDeterministic_probability;
		}
	}

	public void start(){

        //making automatic move on the entire Board
        while (!endOfGame()){
            try {
                Thread.sleep(DELAY);
            } catch (InterruptedException ex) {
                Debug.println("can't sleep");
            }
            for (Iterator<Agent> it = _agents.iterator(); it.hasNext();) {
                Agent agent = it.next();
                System.out.println("\n\nEnd of game in " + this._maxSteps + " steps.");
                System.out.println("=====================\n " + agent.getName()+"'s turn:\n=====================");
                agent.play(Game._board, _agents, _maxSteps);
                try {
                    Thread.sleep(DELAY);
                } catch (InterruptedException ex) {}
                this._maxSteps--;
            }
            //this._maxSteps--;
        }
        finishGame();
    }

    private void finishGame() {
    	System.out.println("\n###############################");
		System.out.println("         Game Finished");
		System.out.println("###############################");
		System.out.println("   Results:");
		for (Iterator<Agent> iterator = Game._agents.iterator(); iterator.hasNext();) {
			Agent agent = iterator.next();
			System.out.println("   - " + agent.getName() + "'s Score: " + agent.getScore());
		}
		System.out.println("###############################");
	}

	public static Vector<Agent> getAgents() {
    	return _agents;
    }

    public void initialize() {

        // For assignment 1:
    	if (this._assignment.equals("1")){
    		Agent moshe = new AgentDumbAuto("sentry", action.RIGHT, this._assignment);
	    	addAgent(moshe);

	        Agent smarty = new AgentSmart("smarty", action.RIGHT, this._assignment);
	        addAgent(smarty);

	        moshe.setEnemy(smarty);
	        smarty.setEnemy(moshe);

	        this._maxSteps = 46;
    	}

    }

    public void placeAgents(){
    	// For assignment 1:
    	if (this._assignment.equals("1")){
	        
    		// configuration for board_Ass1_b:
	        _agents.elementAt(0).initAgentPlaceOnBoard(_board.getSquare(2, 6));
	        _agents.elementAt(1).initAgentPlaceOnBoard(_board.getSquare(4, 7));
    	}
    }

    public int getNumberOfAgents(){
        return _agents.size();
    }

    private void addAgent(Agent newAgent) {
        _agents.addElement(newAgent);
    }

    private boolean endOfGame() {
    	return this._maxSteps == 0 || _board.getFlags().isEmpty();
    }

	public static Agent getOtherPlayer(Agent agent) {
		if (_agents.size() != 2){
			return null;
		}
		else{
			if (_agents.elementAt(0) == agent)
				return _agents.elementAt(1);
			else if (_agents.elementAt(1) == agent)
				return _agents.elementAt(0);
			else
				return null;
		}
	}

	public static boolean isGameZeroSum() {
		return _gameZeroSum;
	}

	public static void increaseScoreBy(int adding, Agent agent, Agent otherAgent) {
    	agent.setScore(agent.getScore() + adding);
    	// If the game is zero sum, decrease other player's score:
    	if ( Game.isGameZeroSum() ){
    		otherAgent.setScore(otherAgent.getScore() - adding);
    	}

	}
}
// configuration for board_Ass1_a:
//_agents.elementAt(0).initAgentPlaceOnBoard(_board.getSquare(2, 5));
////////_agents.elementAt(0).initAgentPlaceOnBoard(_board.getSquare(2, 4));
//_agents.elementAt(1).initAgentPlaceOnBoard(_board.getSquare(6, 1));